package com.tools.common.object;

import com.google.common.util.concurrent.AtomicDouble;
import com.tools.common.object.string.RegEnum;
import com.tools.common.object.string.VerifyKit;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 基本数据类型和其包装类的
 * 枚举，及其对其的一系列操作
 * */
@Note("基本数据类型和其包装类的枚举，及其对其的一系列操作")
public enum BasicEnum {

    BYTE("byte", "java.lang.Byte", 0, byte.class, Byte.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return byteValue(sourceValue); }
    },

    SHORT("short", "java.lang.Short", 0, short.class, Short.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return shortValue(sourceValue); }
    },

    INT("int", "java.lang.Integer", 0, int.class, Integer.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return intValue(sourceValue); }
    },

    LONG("long", "java.lang.Long", 0, long.class, Long.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return longValue(sourceValue); }
    },

    DOUBLE("double", "java.lang.Double", 0.0, double.class, Double.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return doubleValue(sourceValue); }
    },

    FLOAT("float", "java.lang.Float", 0.0f, float.class, Float.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return floatValue(sourceValue); }
    },

    CHAR("char", "java.lang.Character", '\u0000', char.class, Character.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return charValue(sourceValue); }
    },

    BOOLEAN("boolean", "java.lang.Boolean", false, boolean.class, Boolean.class) {
        @Override
        public Object toRealValue(Object sourceValue) { return booleanValue(sourceValue); }
    };

    /* *******************************************************************************************
     *
     *          基本构造器和 Getter / Setter
     *
     * *******************************************************************************************
     * */

    @Note("基本类型的名称")
    private final String name;

    @Note("基本类型对应的包装类的全路径")
    private final String wrapper;

    @Note("作为基本类型，它被声明时默认赋予的值")
    private final Object defaultValue;

    @Note("基本类型数据的字节码，例如：int.class")
    private final Class<?> basicClass;

    @Note("基本类型包装类的字节码，例如：Integer.class")
    private final Class<?> wrapperClass;

    @Note("JavaScript 能正确处理和表示的最大与最小整数")
    public static final BigDecimal JS_SAFE_MAX = new BigDecimal("9007199254740991");
    public static final BigDecimal JS_SAFE_MIN = new BigDecimal("-9007199254740991");

    BasicEnum(String name, String wrapper, Object defaultValue, Class<?> basicClass, Class<?> wrapperClass) {
        this.name = name;
        this.wrapper = wrapper;
        this.defaultValue = defaultValue;
        this.basicClass = basicClass;
        this.wrapperClass = wrapperClass;
    }

    @Note("尽可能地将 sourceValue 对象转为 this 类型的值返回")
    public abstract Object toRealValue(Object sourceValue);

    public String getName() {
        return name;
    }

    public String getWrapper() {
        return wrapper;
    }

    public Object getDefaultValue() {
        return defaultValue;
    }

    public Class<?> getBasicClass() {
        return basicClass;
    }

    public Class<?> getWrapperClass() {
        return wrapperClass;
    }

    public boolean eqBasic(Class<?> targetType) {
        return this.basicClass.equals(targetType);
    }

    public boolean eqWrapper(Class<?> targetType) {
        return this.wrapperClass.equals(targetType);
    }

    public boolean eqBasicOrWrapper(Class<?> targetType) {
        return this.basicClass.equals(targetType) ||
                this.wrapperClass.equals(targetType);
    }

    @Note("根据字节码获取枚举实例，然后获取对应类型的默认值")
    public static Object getDefaultValue(Class<?> objClass) {
        BasicEnum anEnum = getEnumSafe(objClass);
        return (anEnum != null && isBasic(objClass)) ? anEnum.defaultValue : null;
    }

    @Override
    public String toString() {
        return wrapper;
    }

    /* *******************************************************************************************
     *
     *          判断方法
     *
     * *******************************************************************************************
     * */

    @Note("判断字节码映射的实例的类型是否是基本类型的")
    public static boolean isBasic(Class<?> objType) {
        return objType.equals(INT.basicClass) ||
                objType.equals(LONG.basicClass) ||
                objType.equals(DOUBLE.basicClass) ||
                objType.equals(CHAR.basicClass) ||
                objType.equals(BYTE.basicClass) ||
                objType.equals(BOOLEAN.basicClass) ||
                objType.equals(FLOAT.basicClass) ||
                objType.equals(SHORT.basicClass);
    }


    @Note("判断字节码映射的实例的类型是否是基本类型的包装类")
    public static boolean isWrapper(Class<?> objType) {
        return objType.equals(INT.wrapperClass) ||
                objType.equals(LONG.wrapperClass) ||
                objType.equals(DOUBLE.wrapperClass) ||
                objType.equals(CHAR.wrapperClass) ||
                objType.equals(BYTE.wrapperClass) ||
                objType.equals(BOOLEAN.wrapperClass) ||
                objType.equals(FLOAT.wrapperClass) ||
                objType.equals(SHORT.wrapperClass);
    }


    @Note("判断字节码映射的实例的类型是否是基本类型 / 基本类型的包装类")
    public static boolean isBasicOrWrapper(Class<?> objType) {
        return isBasic(objType) || isWrapper(objType);
    }

    public static boolean isBigDecimal(Class<?> objType) {
        return BigDecimal.class.equals(objType);
    }

    public static boolean isBigInteger(Class<?> objType) {
        return BigInteger.class.equals(objType);
    }

    public static boolean isNumber(Class<?> objType) {
        return Number.class.equals(objType);
    }

    public static boolean isAtomicInteger(Class<?> objType) {
        return AtomicInteger.class.equals(objType);
    }

    public static boolean isAtomicLong(Class<?> objType) {
        return AtomicLong.class.equals(objType);
    }

    public static boolean isAtomicDouble(Class<?> objType) {
        return AtomicDouble.class.equals(objType);
    }

    public static boolean isAtomicBoolean(Class<?> objType) {
        return AtomicBoolean.class.equals(objType);
    }


    @Note("将值 1 和值 2 转为相同的基本类型，然后进行比较是否相同")
    public boolean eq(Object srcValue, Object tarValue) {
        switch (this) {
            case INT: return Objects.equals(intValue(srcValue), intValue(tarValue));
            case LONG: return Objects.equals(longValue(srcValue), longValue(tarValue));
            case DOUBLE: return Objects.equals(doubleValue(srcValue), doubleValue(tarValue));
            case FLOAT: return Objects.equals(floatValue(srcValue), floatValue(tarValue));
            case CHAR: return Objects.equals(charValue(srcValue), charValue(tarValue));
            case SHORT: return Objects.equals(shortValue(srcValue), shortValue(tarValue));
            case BYTE: return Objects.equals(byteValue(srcValue), byteValue(tarValue));
            default: return Objects.equals(booleanValue(srcValue), booleanValue(tarValue));
        }
    }

    @Note("判断数字是否超出了 JavaScript 能处理的最大整数")
    public static boolean isNotInJSMaxRange(Number number) {
        if (number == null) {
            return false;
        }
        BigDecimal bigDecimal;
        if (number instanceof BigDecimal) {
            bigDecimal = (BigDecimal) number;
        } else {
            bigDecimal = new BigDecimal(number.toString());
        }
        // 判断整数是否超出 JS 安全范围
        if (bigDecimal.scale() == 0) {
            return bigDecimal.compareTo(JS_SAFE_MAX) > 0 || bigDecimal.compareTo(JS_SAFE_MIN) < 0;
        }
        // 判断小数是否超过 16 位有效数字
        return bigDecimal.precision() > 16;
    }


    /* *******************************************************************************************
     *
     *          获取枚举实例
     *
     * *******************************************************************************************
     * */


    @Note("根据基本类型的名称或者包装类的全路径安全地获取映射的枚举实例，获取不到不会抛出移除")
    public static BasicEnum getEnumSafe(String nameOrWrapper) {
        if(INT.name.equalsIgnoreCase(nameOrWrapper) || INT.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return INT;
        }
        if(LONG.name.equalsIgnoreCase(nameOrWrapper) || LONG.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return LONG;
        }
        if(DOUBLE.name.equalsIgnoreCase(nameOrWrapper) || DOUBLE.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return DOUBLE;
        }
        if(CHAR.name.equalsIgnoreCase(nameOrWrapper) || CHAR.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return CHAR;
        }
        if(BYTE.name.equalsIgnoreCase(nameOrWrapper) || BYTE.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return BYTE;
        }
        if(BOOLEAN.name.equalsIgnoreCase(nameOrWrapper) || BOOLEAN.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return BOOLEAN;
        }
        if(FLOAT.name.equalsIgnoreCase(nameOrWrapper) || FLOAT.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return FLOAT;
        }
        if(SHORT.name.equalsIgnoreCase(nameOrWrapper) || SHORT.wrapper.equalsIgnoreCase(nameOrWrapper)) {
            return SHORT;
        }
        return null;
    }

    @Note("不安全地获取实例，若获取不到会抛出移除")
    public static BasicEnum getEnum(String nameOrWrapper) {
        BasicEnum basicEnum = getEnumSafe(nameOrWrapper);
        if(basicEnum == null) throw new IllegalArgumentException("不知道 " + nameOrWrapper + " 对应的枚举实例");
        return basicEnum;
    }


    @Note("不安全地获取实例，若获取不到会抛出移除")
    public static BasicEnum getEnumSafe(Class<?> objType) {
        if(INT.basicClass.equals(objType) || INT.wrapperClass.equals(objType)) {
            return INT;
        }
        if(LONG.basicClass.equals(objType) || LONG.wrapperClass.equals(objType)) {
            return LONG;
        }
        if(DOUBLE.basicClass.equals(objType) || DOUBLE.wrapperClass.equals(objType)) {
            return DOUBLE;
        }
        if(CHAR.basicClass.equals(objType) || CHAR.wrapperClass.equals(objType)) {
            return CHAR;
        }
        if(BYTE.basicClass.equals(objType) || BYTE.wrapperClass.equals(objType)) {
            return BYTE;
        }
        if(BOOLEAN.basicClass.equals(objType) || BOOLEAN.wrapperClass.equals(objType)) {
            return BOOLEAN;
        }
        if(FLOAT.basicClass.equals(objType) || FLOAT.wrapperClass.equals(objType)) {
            return FLOAT;
        }
        if(SHORT.basicClass.equals(objType) || SHORT.wrapperClass.equals(objType)) {
            return SHORT;
        }
        return null;
    }

    @Note("根据基本类型或包装类的字节码安全地获取映射的枚举实例，获取不到不会抛出移除")
    public static BasicEnum getEnum(Class<?> objType) {
        BasicEnum basicEnum = getEnumSafe(objType);
        if(basicEnum == null) throw new IllegalArgumentException("不知道 " + objType + " 对应的枚举实例");
        return basicEnum;
    }

    @Note("安全地根据 name 来获取基本类型的字节码实例，获取不到不会抛异常")
    public static Class<?> getBasicClassByNameSafe(String name) {
        if(name == null) return null;
        switch(name.toLowerCase(Locale.ROOT)) {
            case "int": return int.class;
            case "long": return long.class;
            case "double": return double.class;
            case "float": return float.class;
            case "boolean": return boolean.class;
            case "char": return char.class;
            case "byte": return byte.class;
            case "short": return short.class;
            default: return null;
        }
    }

    @Note("直接根据 name 来获取基本类型的字节码实例，获取不到会抛异常")
    public static Class<?> getBasicClassByName(String name) {
        Class<?> basicClass = getBasicClassByNameSafe(name);
        if(basicClass == null) throw new IllegalArgumentException("不知道 " + name + " 是基本类型");
        return basicClass;
    }

    /* *******************************************************************************************
     *
     *          值的转换操作
     *
     * *******************************************************************************************
     * */

    @Note("整形数字转为布尔值的默认条件")
    public static boolean intToBoolean(int value) {
        return value != 0;
    }

    @Note("字符类型转为布尔值的默认条件")
    public static boolean charToBoolean(char value) {
        return value != 0 && value != 48;
    }

    @Note("若数字超出了 JavaScript 能处理的最大整数，那就返回字符串，否则正常返回数字")
    public static Object getNumberOrStringByJSMaxRange(Number number) {
        return isNotInJSMaxRange(number) ? number.toString() : number;
    }


    @Note("自动校验目标类型，并返回相匹配的类型。如果匹配不上那就返回 null")
    public static Object matchAndGetValue(Object sourceValue, Class<?> targetClass) {
        BasicEnum basic = getEnumSafe(targetClass);
        if(basic != null) {
            return basic.toRealValue(sourceValue);
        }
        if(BasicEnum.isBigDecimal(targetClass)) {
            return BasicEnum.bigDecimalValue(sourceValue);
        }
        if(BasicEnum.isBigInteger(targetClass)) {
            return BasicEnum.bigDecimalValue(sourceValue);
        }
        if(BasicEnum.isAtomicInteger(targetClass)) {
            return BasicEnum.bigDecimalValue(sourceValue);
        }
        if(BasicEnum.isAtomicLong(targetClass)) {
            return BasicEnum.bigDecimalValue(sourceValue);
        }
        if(BasicEnum.isAtomicDouble(targetClass)) {
            return BasicEnum.bigDecimalValue(sourceValue);
        }
        if(BasicEnum.isAtomicBoolean(targetClass)) {
            return BasicEnum.bigDecimalValue(sourceValue);
        }
        if(BasicEnum.isNumber(targetClass)) {
            return BasicEnum.bigDecimalValue(sourceValue);
        }
        return null;
    }


    @Note("将 srcValue 对象转为字节型数据返回")
    public static Byte byteValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Number) return ((Number) srcValue).byteValue();
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) return ObjKit.stringToWholeNumber(s).byteValue();
            if(s.equalsIgnoreCase("true")) return 1;
            if(s.equalsIgnoreCase("false")) return 0;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return (byte) Character.getNumericValue(c);
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Byte 类型");
        }
        if(srcValue instanceof Boolean) return (byte) (((Boolean) srcValue) ? 1 : 0);
        if(srcValue instanceof Character) return (byte) Character.getNumericValue((Character) srcValue);
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Byte 类型");
    }

    @Note("将 srcValue 对象转为短整型数据返回")
    public static Short shortValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Number) return ((Number) srcValue).shortValue();
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) return ObjKit.stringToWholeNumber(s).shortValue();
            if(s.equalsIgnoreCase("true")) return 1;
            if(s.equalsIgnoreCase("false")) return 0;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return (short) Character.getNumericValue(c);
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Short 类型");
        }
        if(srcValue instanceof Boolean) return (short) (((Boolean) srcValue) ? 1 : 0);
        if(srcValue instanceof Character) return (short) Character.getNumericValue((Character) srcValue);
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Short 类型");
    }


    @Note("将 srcValue 对象转为整型数据返回")
    public static Integer intValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Number) return ((Number) srcValue).intValue();
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) return ObjKit.stringToWholeNumber(s).intValue();
            if(s.equalsIgnoreCase("true")) return 1;
            if(s.equalsIgnoreCase("false")) return 0;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return Character.getNumericValue(c);
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Integer 类型");
        }
        if(srcValue instanceof Boolean) return ((Boolean) srcValue) ? 1 : 0;
        if(srcValue instanceof Character) return Character.getNumericValue((Character) srcValue);
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Integer 类型");
    }


    @Note("将 srcValue 对象转为长整型数据返回")
    public static Long longValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Number) return ((Number) srcValue).longValue();
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) return ObjKit.stringToWholeNumber(s).longValue();
            if(s.equalsIgnoreCase("true")) return 1L;
            if(s.equalsIgnoreCase("false")) return 0L;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return (long) Character.getNumericValue(c);
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Long 类型");
        }
        if(srcValue instanceof Boolean) return ((Boolean) srcValue) ? 1L : 0L;
        if(srcValue instanceof Character) return (long) Character.getNumericValue((Character) srcValue);
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Long 类型");
    }


    @Note("将 srcValue 对象转为双精度浮点型数据返回")
    public static Double doubleValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Number) return ((Number) srcValue).doubleValue();
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) return ObjKit.stringToFloatNumber(s).doubleValue();
            if(s.equalsIgnoreCase("true")) return 1.0;
            if(s.equalsIgnoreCase("false")) return 0.0;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return (double) Character.getNumericValue(c);
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Double 类型");
        }
        if(srcValue instanceof Boolean) return ((Boolean) srcValue) ? 1.0 : 0.0;
        if(srcValue instanceof Character) return (double) Character.getNumericValue((Character) srcValue);
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Double 类型");
    }



    @Note("将 srcValue 对象转为单精度浮点型数据返回")
    public static Float floatValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Number) return ((Number) srcValue).floatValue();
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) return ObjKit.stringToFloatNumber(s).floatValue();
            if(s.equalsIgnoreCase("true")) return 1.0F;
            if(s.equalsIgnoreCase("false")) return 0.0F;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return (float) Character.getNumericValue(c);
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Float 类型");
        }
        if(srcValue instanceof Boolean) return ((Boolean) srcValue) ? 1.0F : 0.0F;
        if(srcValue instanceof Character) return (float) Character.getNumericValue((Character) srcValue);
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Float 类型");
    }


    @Note("将 srcValue 对象转为布尔型数返回")
    public static Boolean booleanValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Boolean) return (Boolean) srcValue;
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(VerifyKit.isBoolean(s)) return "true".equalsIgnoreCase(s);
            if(RegEnum.IS_NUMBER.match(s)) {
                int value = ObjKit.stringToWholeNumber(s).intValue();
                return intToBoolean(value);
            }
            if(s.length() == 1) return intToBoolean(s.charAt(0));
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Boolean 类型");
        }
        if(srcValue instanceof Number) return intToBoolean(((Number) srcValue).intValue());
        if(srcValue instanceof Character) return charToBoolean((Character) srcValue);
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Boolean 类型");
    }

    @Note("将 srcValue 对象转为字符型数返回")
    public static Character charValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Character) return (Character) srcValue;
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(s.isEmpty()) return (Character) CHAR.defaultValue;
            if(s.length() == 1) return s.charAt(0);
            if(s.equalsIgnoreCase("true")) return '1';
            if(s.equalsIgnoreCase("false")) return '0';
            if(RegEnum.IS_NUMBER.match(s)) {
                int value = ObjKit.stringToWholeNumber(s).intValue();
                return (char) value;
            }
            return s.charAt(0);
        }
        if(srcValue instanceof Number) {
            int value = ((Number) srcValue).intValue();
            return (char) value;
        }
        if(srcValue instanceof Boolean) return ((Boolean) srcValue) ? '1' : '0';
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Character 类型");
    }


    @Note("将 src 转为 Number 数字")
    public static Number numberValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof Number) return (Number) srcValue;
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(VerifyKit.isWholeNumber(s)) return ObjKit.stringToWholeNumber(s);
            if(VerifyKit.isFloat(s)) return ObjKit.stringToFloatNumber(s);
            if(s.equalsIgnoreCase("true")) return 1;
            if(s.equalsIgnoreCase("false")) return 0;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return Character.getNumericValue(c);
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.lang.Number 类型");
        }
        if(srcValue instanceof Boolean) {
            return ((Boolean) srcValue) ? 1 : 0;
        }
        if(srcValue instanceof Character) {
            Character c = (Character) srcValue;
            return Character.getNumericValue(c);
        }
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.lang.Number 类型");
    }


    @Note("将目标类型转为 java.math.BigDecimal")
    public static BigDecimal bigDecimalValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof BigDecimal) return (BigDecimal) srcValue;
        if(srcValue instanceof Number) return new BigDecimal(srcValue.toString());
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) return new BigDecimal(s);
            if(s.equalsIgnoreCase("true")) return new BigDecimal("1");
            if(s.equalsIgnoreCase("false")) return new BigDecimal("0");
            if(s.length() == 1) {
                char c = s.charAt(0);
                return BigDecimal.valueOf(Character.getNumericValue(c));
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.math.BigDecimal 类型");
        }
        if(srcValue instanceof Boolean) {
            return ((Boolean) srcValue) ? new BigDecimal("1") : new BigDecimal("0");
        }
        if(srcValue instanceof Character) {
            Character c = (Character) srcValue;
            return new BigDecimal(Character.getNumericValue(c));
        }
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.math.BigDecimal 类型");
    }

    @Note("将目标类型转为 java.math.BigInteger")
    public static BigInteger bigIntegerValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof BigInteger) return (BigInteger) srcValue;
        if(srcValue instanceof Number) return BigInteger.valueOf(((Number) srcValue).longValue());
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) {
                Number number = ObjKit.stringToWholeNumber(s);
                return (number instanceof BigInteger) ? (BigInteger) number : new BigInteger(number.toString());
            }
            if(s.equalsIgnoreCase("true")) return BigInteger.ONE;
            if(s.equalsIgnoreCase("false")) return BigInteger.ZERO;
            if(s.length() == 1) {
                char c = s.charAt(0);
                return BigInteger.valueOf(Character.getNumericValue(c));
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.math.BigInteger 类型");
        }
        if(srcValue instanceof Boolean) {
            return ((Boolean) srcValue) ? BigInteger.ONE : BigInteger.ZERO;
        }
        if(srcValue instanceof Character) {
            Character c = (Character) srcValue;
            return BigInteger.valueOf(Character.getNumericValue(c));
        }
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.math.BigInteger 类型");
    }


    @Note("将目标类型转为 java.util.concurrent.atomic.AtomicInteger")
    public static AtomicInteger atomicIntegerValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof AtomicInteger) return (AtomicInteger) srcValue;
        if(srcValue instanceof Number) return new AtomicInteger(((Number) srcValue).intValue());
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) {
                Number number = ObjKit.stringToWholeNumber(s);
                return new AtomicInteger(number.intValue());
            }
            if(s.equalsIgnoreCase("true")) return new AtomicInteger(1);
            if(s.equalsIgnoreCase("false")) return new AtomicInteger(0);
            if(s.length() == 1) {
                char c = s.charAt(0);
                return new AtomicInteger(Character.getNumericValue(c));
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.util.concurrent.atomic.AtomicInteger 类型");
        }
        if(srcValue instanceof Boolean) {
            return ((Boolean) srcValue) ? new AtomicInteger(1) : new AtomicInteger(0);
        }
        if(srcValue instanceof Character) {
            Character c = (Character) srcValue;
            return new AtomicInteger(Character.getNumericValue(c));
        }
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.util.concurrent.atomic.AtomicInteger 类型");
    }


    @Note("将目标类型转为 java.util.concurrent.atomic.AtomicLong")
    public static AtomicLong atomicLongValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof AtomicLong) return (AtomicLong) srcValue;
        if(srcValue instanceof Number) return new AtomicLong(((Number) srcValue).longValue());
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(VerifyKit.isWholeNumber(s)) {
                Number number = ObjKit.stringToWholeNumber(s);
                return new AtomicLong(number.longValue());
            }
            if(s.equalsIgnoreCase("true")) return new AtomicLong(1);
            if(s.equalsIgnoreCase("false")) return new AtomicLong(0);
            if(s.length() == 1) {
                char c = s.charAt(0);
                return new AtomicLong(Character.getNumericValue(c));
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.util.concurrent.atomic.AtomicLong 类型");
        }
        if(srcValue instanceof Boolean) {
            return ((Boolean) srcValue) ? new AtomicLong(1) : new AtomicLong(0);
        }
        if(srcValue instanceof Character) {
            Character c = (Character) srcValue;
            return new AtomicLong(Character.getNumericValue(c));
        }
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.util.concurrent.atomic.AtomicLong 类型");
    }



    @Note("将目标类型转为 java.util.concurrent.atomic.AtomicDouble")
    public static AtomicDouble atomicDoubleValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof AtomicDouble) return (AtomicDouble) srcValue;
        if(srcValue instanceof Number) return new AtomicDouble(((Number) srcValue).doubleValue());
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(RegEnum.IS_NUMBER.match(s)) {
                Number number = ObjKit.stringToFloatNumber(s);
                return new AtomicDouble(number.doubleValue());
            }
            if(s.equalsIgnoreCase("true")) return new AtomicDouble(1.0);
            if(s.equalsIgnoreCase("false")) return new AtomicDouble(0.0);
            if(s.length() == 1) {
                char c = s.charAt(0);
                return new AtomicDouble(Character.getNumericValue(c));
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.util.concurrent.atomic.AtomicDouble 类型");
        }
        if(srcValue instanceof Boolean) {
            return ((Boolean) srcValue) ? new AtomicDouble(1.0) : new AtomicDouble(0.0);
        }
        if(srcValue instanceof Character) {
            Character c = (Character) srcValue;
            return new AtomicDouble(Character.getNumericValue(c));
        }
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.util.concurrent.atomic.AtomicDouble 类型");
    }



    @Note("将目标类型转为 java.util.concurrent.atomic.AtomicBoolean")
    public static AtomicBoolean atomicBooleanValue(Object srcValue) {
        if(srcValue == null) return null;
        if(srcValue instanceof AtomicBoolean) return (AtomicBoolean) srcValue;
        if(srcValue instanceof Boolean) return new AtomicBoolean((Boolean) srcValue);
        if(srcValue instanceof String) {
            String s = (String) srcValue;
            if(VerifyKit.isBoolean(s)) return new AtomicBoolean(Boolean.parseBoolean(s));
            if(RegEnum.IS_NUMBER.match(s)) {
                Number number = ObjKit.stringToWholeNumber(s);
                return new AtomicBoolean(intToBoolean(number.intValue()));
            }
            if(s.length() == 1) {
                char c = s.charAt(0);
                return new AtomicBoolean(intToBoolean(Character.getNumericValue(c)));
            }
            throw new ClassCastException("【" + s + "】 不能转为 java.util.concurrent.atomic.AtomicBoolean 类型");
        }
        if(srcValue instanceof Number) return new AtomicBoolean(intToBoolean(((Number) srcValue).intValue()));
        if(srcValue instanceof Character) {
            Character c = (Character) srcValue;
            return new AtomicBoolean(intToBoolean(Character.getNumericValue(c)));
        }
        throw new ClassCastException("【" + srcValue + "】-【" + srcValue.getClass().getName() + "】 不能转为 java.util.concurrent.atomic.AtomicBoolean 类型");
    }





    @Note("若 c 是小写字母字符，则将其转为大写返回")
    public char toUpper(char c) {
        if(this != CHAR) throw new IllegalArgumentException("该方法的调用者必须是 BasicEnum.CHAR 实例");
        if(c < 97 || c > 122) throw new IllegalArgumentException("入参字符必须是小写英文字母");
        switch (c) {
            case 'a' : return 'A';
            case 'b' : return 'B';
            case 'c' : return 'C';
            case 'd' : return 'D';
            case 'e' : return 'E';
            case 'f' : return 'F';
            case 'g' : return 'G';
            case 'h' : return 'H';
            case 'i' : return 'I';
            case 'j' : return 'J';
            case 'k' : return 'K';
            case 'l' : return 'L';
            case 'm' : return 'M';
            case 'n' : return 'N';
            case 'o' : return 'O';
            case 'p' : return 'P';
            case 'q' : return 'Q';
            case 'r' : return 'R';
            case 's' : return 'S';
            case 't' : return 'T';
            case 'u' : return 'U';
            case 'v' : return 'V';
            case 'x' : return 'X';
            case 'y' : return 'Y';
            case 'z' : return 'Z';
        }
        throw new IllegalArgumentException("入参字符必须是小写英文字母");
    }


    @Note("若 c 是大写字母字符，则将其转为小写返回")
    public char toLower(char c) {
        if(this != CHAR) throw new IllegalArgumentException("该方法的调用者必须是 BasicEnum.CHAR 实例");
        if(c < 65 || c > 90) throw new IllegalArgumentException("入参字符必须是大写英文字母");
        switch (c) {
            case 'A' : return 'a';
            case 'B' : return 'b';
            case 'C' : return 'c';
            case 'D' : return 'd';
            case 'E' : return 'e';
            case 'F' : return 'f';
            case 'G' : return 'g';
            case 'H' : return 'h';
            case 'I' : return 'i';
            case 'J' : return 'j';
            case 'K' : return 'k';
            case 'L' : return 'l';
            case 'M' : return 'm';
            case 'N' : return 'n';
            case 'O' : return 'o';
            case 'P' : return 'p';
            case 'Q' : return 'q';
            case 'R' : return 'r';
            case 'S' : return 's';
            case 'T' : return 't';
            case 'U' : return 'u';
            case 'V' : return 'v';
            case 'X' : return 'x';
            case 'Y' : return 'y';
            case 'Z' : return 'z';
        }
        throw new IllegalArgumentException("入参字符必须是大写英文字母");
    }

    @Note("将 4 个字节的数据转为 int 类型的整数")
    public static int byteArrayToInt(byte[] bys) {
        if(bys == null) return 0;
        if(bys.length != 4) throw new IllegalArgumentException("byte 字节数组的长度必须为 4");
        return (bys[0] << 24) + (bys[1] << 16) + (bys[2] << 8) + bys[3];
    }

    @Note("将 int 类型的整数转为 4 个字节的数组")
    public static byte[] intToByteArray(int num) {
        byte[] res = new byte[4];
        for (int i = 0; i < 4; i++) {
            res[i] = (byte) ((num >> ((4 - i - 1) * 8)) & 0xFF);
        }
        return res;
    }

    /* *******************************************************************************************
     *
     *           基本类型数组 -> 包装类数组
     *
     * *******************************************************************************************
     * */

    public static Integer[] toWrapperArray(int... ints) {
        return toWrapperArray(null, ints);
    }

    public static Integer[] toWrapperArray(Force<Integer> force, int... ints) {
        if(ints == null || ints.length == 0) return new Integer[0];
        return (Integer[]) private_toWrapperArray(INT, ints, force);
    }

    public static Long[] toWrapperArray(long... longs) {
        return toWrapperArray(null, longs);
    }

    public static Long[] toWrapperArray(Force<Long> force, long... longs) {
        if(longs == null || longs.length == 0) return new Long[0];
        return (Long[]) private_toWrapperArray(LONG, longs, force);
    }

    public static Double[] toWrapperArray(double... doubles) {
        return toWrapperArray(null, doubles);
    }

    public static Double[] toWrapperArray(Force<Double> force, double... doubles) {
        if(doubles == null || doubles.length == 0) return new Double[0];
        return (Double[]) private_toWrapperArray(DOUBLE, doubles, force);
    }

    public static Float[] toWrapperArray(float... floats) {
        return toWrapperArray(null, floats);
    }

    public static Float[] toWrapperArray(Force<Float> force, float... floats) {
        if(floats == null || floats.length == 0) return new Float[0];
        return (Float[]) private_toWrapperArray(FLOAT, floats, force);
    }

    public static Character[] toWrapperArray(char... chars) {
        return toWrapperArray(null, chars);
    }

    public static Character[] toWrapperArray(Force<Character> force, char... chars) {
        if(chars == null || chars.length == 0) return new Character[0];
        return (Character[]) private_toWrapperArray(CHAR, chars, force);
    }

    public static Byte[] toWrapperArray(byte... chars) {
        return toWrapperArray(null, chars);
    }

    public static Byte[] toWrapperArray(Force<Byte> force, byte... bytes) {
        if(bytes == null || bytes.length == 0) return new Byte[0];
        return (Byte[]) private_toWrapperArray(BYTE, bytes, force);
    }

    public static Short[] toWrapperArray(short... shorts) {
        return toWrapperArray(null, shorts);
    }

    public static Short[] toWrapperArray(Force<Short> force, short... shorts) {
        if(shorts == null || shorts.length == 0) return new Short[0];
        return (Short[]) private_toWrapperArray(SHORT, shorts, force);
    }

    public static Boolean[] toWrapperArray(boolean... booleans) {
        return toWrapperArray(null, booleans);
    }

    public static Boolean[] toWrapperArray(Force<Boolean> force, boolean... booleans) {
        if(booleans == null || booleans.length == 0) return new Boolean[0];
        return (Boolean[]) private_toWrapperArray(BOOLEAN, booleans, force);
    }

    /* *******************************************************************************************
     *
     *           包装类数组 -> 基本类型数组
     *
     * *******************************************************************************************
     * */

    public static int[] toBasicArray(Integer... ints) {
        return toBasicArray(null, ints);
    }

    public static int[] toBasicArray(Force<Integer> force, Integer... ints) {
        if(ints == null || ints.length == 0) return new int[0];
        return (int[]) private_toBasicArray(INT, ints, force);
    }

    public static long[] toBasicArray(Long... longs) {
        return toBasicArray(null, longs);
    }

    public static long[] toBasicArray(Force<Long> force, Long... longs) {
        if(longs == null || longs.length == 0) return new long[0];
        return (long[]) private_toBasicArray(LONG, longs, force);
    }

    public static double[] toBasicArray(Double... doubles) {
        return toBasicArray(null, doubles);
    }

    public static double[] toBasicArray(Force<Double> force, Double... doubles) {
        if(doubles == null || doubles.length == 0) return new double[0];
        return (double[]) private_toBasicArray(DOUBLE, doubles, force);
    }

    public static float[] toBasicArray(Float... longs) {
        return toBasicArray(null, longs);
    }

    public static float[] toBasicArray(Force<Float> force, Float... floats) {
        if(floats == null || floats.length == 0) return new float[0];
        return (float[]) private_toBasicArray(FLOAT, floats, force);
    }

    public static char[] toBasicArray(Character... chars) {
        return toBasicArray(null, chars);
    }

    public static char[] toBasicArray(Force<Character> force, Character... chars) {
        if(chars == null || chars.length == 0) return new char[0];
        return (char[]) private_toBasicArray(CHAR, chars, force);
    }

    public static byte[] toBasicArray(Byte... bytes) {
        return toBasicArray(null, bytes);
    }

    public static byte[] toBasicArray(Force<Byte> force, Byte... bytes) {
        if(bytes == null || bytes.length == 0) return new byte[0];
        return (byte[]) private_toBasicArray(BYTE, bytes, force);
    }

    public static short[] toBasicArray(Short... shorts) {
        return toBasicArray(null, shorts);
    }

    public static short[] toBasicArray(Force<Short> force, Short... shorts) {
        if(shorts == null || shorts.length == 0) return new short[0];
        return (short[]) private_toBasicArray(SHORT, shorts, force);
    }

    public static boolean[] toBasicArray(Boolean... booleans) {
        return toBasicArray(null, booleans);
    }

    public static boolean[] toBasicArray(Force<Boolean> force, Boolean... booleans) {
        if(booleans == null || booleans.length == 0) return new boolean[0];
        return (boolean[]) private_toBasicArray(BOOLEAN, booleans, force);
    }


    /* *******************************************************************************************
     *
     *           私有逻辑
     *
     * *******************************************************************************************
     * */

    @Note("将基本类型数组转为包装类数组的逻辑")
    private static Object private_toWrapperArray(BasicEnum basic, Object sourceArray, Force force) {
        switch (basic) {
            case INT: {
                int[] src = (int[]) sourceArray;
                int length = src.length;
                Integer[] res = new Integer[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Integer) force.force(src[i]);
                return res;
            }
            case LONG: {
                long[] src = (long[]) sourceArray;
                int length = src.length;
                Long[] res = new Long[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Long) force.force(src[i]);
                return res;
            }
            case DOUBLE: {
                double[] src = (double[]) sourceArray;
                int length = src.length;
                Double[] res = new Double[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Double) force.force(src[i]);
                return res;
            }
            case FLOAT: {
                float[] src = (float[]) sourceArray;
                int length = src.length;
                Float[] res = new Float[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Float) force.force(src[i]);
                return res;
            }
            case CHAR: {
                char[] src = (char[]) sourceArray;
                int length = src.length;
                Character[] res = new Character[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Character) force.force(src[i]);
                return res;
            }
            case BYTE: {
                byte[] src = (byte[]) sourceArray;
                int length = src.length;
                Byte[] res = new Byte[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Byte) force.force(src[i]);
                return res;
            }
            case SHORT: {
                short[] src = (short[]) sourceArray;
                int length = src.length;
                Short[] res = new Short[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Short) force.force(src[i]);
                return res;
            }
            default: {
                boolean[] src = (boolean[]) sourceArray;
                int length = src.length;
                Boolean[] res = new Boolean[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else for (int i = 0; i < length; i++) res[i] = (Boolean) force.force(src[i]);
                return res;
            }
        }
    }


    @Note("将包装类数组转为基本类型数组的逻辑")
    private static Object private_toBasicArray(BasicEnum basic, Object sourceArray, Force force) {
        switch (basic) {
            case INT: {
                Integer[] src = (Integer[]) sourceArray;
                int length = src.length;
                int[] res = new int[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = (o == null) ? 0 : (Integer) o;
                    }
                }
                return res;
            }
            case LONG: {
                Long[] src = (Long[]) sourceArray;
                int length = src.length;
                long[] res = new long[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = (o == null) ? 0 : (Long) o;
                    }
                }
                return res;
            }
            case DOUBLE: {
                Double[] src = (Double[]) sourceArray;
                int length = src.length;
                double[] res = new double[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = (o == null) ? 0.0 : (Double) o;
                    }
                }
                return res;
            }
            case FLOAT: {
                Float[] src = (Float[]) sourceArray;
                int length = src.length;
                float[] res = new float[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = (o == null) ? 0.0f : (Float) o;
                    }
                }
                return res;
            }
            case CHAR: {
                Character[] src = (Character[]) sourceArray;
                int length = src.length;
                char[] res = new char[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = (o == null) ? '\u0000' : (Character) o;
                    }
                }
                return res;
            }
            case BYTE: {
                Byte[] src = (Byte[]) sourceArray;
                int length = src.length;
                byte[] res = new byte[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = (o == null) ? 0 : (Byte) o;
                    }
                }
                return res;
            }
            case SHORT: {
                Short[] src = (Short[]) sourceArray;
                int length = src.length;
                short[] res = new short[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = (o == null) ? 0 : (Short) o;
                    }
                }
                return res;
            }
            default: {
                Boolean[] src = (Boolean[]) sourceArray;
                int length = src.length;
                boolean[] res = new boolean[length];
                if(force == null) for (int i = 0; i < length; i++) res[i] = src[i];
                else {
                    for (int i = 0; i < length; i++) {
                        Object o = force.force(src[i]);
                        res[i] = o != null && (Boolean) o;
                    }
                }
                return res;
            }
        }
    }


    @Note("其他类型转为布尔值")
    private static boolean private_booleanValueByOtherType(Object o) {
        if(o instanceof Number) {
            return intToBoolean(((Number) o).intValue());
        }
        if(o instanceof Character) {
            return charToBoolean((Character) o);
        }
        throw new ClassCastException("【" + o.getClass().getName() + "】 不能转为 boolean/Boolean 单精度浮点型数值");
    }

}
